 ///
 /// @file    Mystring.cc
 /// @author  lemon(haohb13@gmail.com)
 /// @date    2023-04-25 09:51:25
 ///
 
#include <string.h>

#include <vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;

class String
{
public:
	String()
	: _pstr(new char[1]())
	{	cout << "String()" << endl;	}

    //explicit
	String(const char *pstr)
	: _pstr(new char[strlen(pstr) + 1]())
	{
		strcpy(_pstr, pstr);
		cout << "String(const char*)" << endl;
	}

    //移动构造函数
    String(String && rhs)
    : _pstr(rhs._pstr)
    {   //时间复杂为O(1)
        rhs._pstr = nullptr;
        cout << "String(String&&)" << endl;
    }

    //移动赋值运算符函数(移动赋值函数)
    String& operator=(String && rhs)
    {
        if(this != &rhs) {//1. 自移动
            cout << "String & operator=(String &&)" << endl;
            delete [] _pstr;//2. 回收左操作数申请的空间
            _pstr = rhs._pstr;//3. 移动操作
            rhs._pstr = nullptr;
        }
        return *this;//4. return*this
    }

    //拷贝构造函数
	String(const String &rhs)
	: _pstr(new char[strlen(rhs._pstr) + 1]())
	{
		strcpy(_pstr, rhs._pstr);
		cout << "String(const String&)" << endl;
	}

    //赋值运算符函数(赋值函数)
	String &operator=(const String &rhs)
	{
        cout << "String& operator=(const String&)" << endl;
		if(this != &rhs) {
			delete [] _pstr;
			_pstr = new char[strlen(rhs._pstr) + 1]();
			strcpy(_pstr, rhs._pstr);
		}
		return *this;
	}

	~String()
	{
		delete [] _pstr;
		_pstr = nullptr;
		cout << "~String()" << endl;
	}

	void print() {
		if(_pstr) {
			cout << _pstr << endl;
		}
	}
    size_t length() const { return strlen(_pstr);   }
    const char * c_str() const {    return _pstr;   }

    friend std::ostream & operator<<(std::ostream & os, const String & rhs);
private:
	char * _pstr;
};

std::ostream & operator<<(std::ostream & os, const String & rhs)
{
    if(rhs._pstr){
        os << rhs._pstr;
    }
    return os;
}

//当类中同时提供了具有移动语义的函数和具有复制控制语义的函数时，
//拷贝构造函数的调用时机也相应的有了变化:
//当函数的返回值是对象时，还要根据所返回的对象的生命周期来决定
//调用哪一个函数
//
//当返回的对象是一个即将被销毁的对象(右值)，此时调用移动构造函数
//当返回的对象是一个持久对象时，此时调用的是拷贝构造函数

String func1()
{   //s1是局部对象，也是一个即将被销毁的对象
    String s1("hello");
    cout << "s1:" << s1 << endl;
    return s1;//调用的是移动构造函数
}

void test0()
{
    func1();
}


String global("world");
String func2()
{//global是一个全局对象，当函数执行结束之后，生命周期还在
    cout << "global:" << global << endl;
    return global;//调用的是拷贝构造函数
}

void test1()
{
    func2();
}

int main(void)
{
	test0();
	/* test1(); */
	return 0;
}
